/*
 * Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
 *
 * This file is part of SeMoLearning.
 *
 * SeMoLearning is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * SeMoLearning is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with SeMoLearning.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef SEMOL_H_
#define SEMOL_H_

#include "semol/core/SemolExp.h" // DLL export/import defines

#include <utilite/USemaphore.h>
#include <utilite/UMutex.h>
#include <utilite/UVariant.h>

#include "semol/core/Parameters.h"
#include "semol/core/Sensor.h"
#include "semol/core/Actuator.h"
#include "semol/core/Node.h"
#include "semol/core/Statistics.h"

#include <opencv2/core/core.hpp>
#include <list>
#include <stack>
#include <set>

namespace semol
{

class HypVerificator;
class Memory;
class BayesFilter;

class SEMOL_EXP Semol
{
public:
	enum VhStrategy {kVhNone, kVhEpipolar, kVhUndef};

	static const char * kDefaultIniFileName;
	static const char * kDefaultIniFilePath;
	static const char * kDefaultDatabaseName;

public:
	static std::string getVersion();
	static std::string getIniFilePath();
	static void readParameters(const std::string & configFile, ParametersMap & parameters);
	static void writeParameters(const std::string & configFile, const ParametersMap & parameters);

public:
	Semol();
	virtual ~Semol();

	bool process(const SensorRaw & data); // for convenience when only one sensor is used
	bool process(const std::list<SensorRaw> & sensors, const std::list<Actuator> & actuators = std::list<Actuator>());

	void dumpData() const;
	void dumpPrediction() const;
	void resetMemory(bool dbOverwritten = false);
	void generateGraph(const std::string & path, int id=0, int margin=4);

	void parseParameters(const ParametersMap & parameters);
	void init(const ParametersMap & param, bool deleteMemory = true);
	void init(const std::string & configFile = "", bool deleteMemory = true);
	void close();

	const std::string & getWorkingDir() const {return _wDir;}
	int getLoopClosureId() const;
	int getReactivatedId() const;
	int getLastSignatureId() const;
	float getLcHypValue() const {return _lastLcHypothesisValue;}
	const std::list<Actuator> & getActuator() const {return _actuatorsLink.actuators();}
	std::list<int> getWorkingMem() const;
	std::set<int> getStMem() const;
	std::map<int, int> getWeights() const;
	int getTotalMemSize() const;
	const Statistics & getStatistics() const {return statistics_;}

	void setMaxTimeAllowed(float maxTimeAllowed); // in ms
	void setDataBufferSize(int size);
	void setWorkingDirectory(std::string path);

	void adjustLikelihood(std::map<int, std::vector<float> > & likelihood) const;
	std::pair<int, float> selectHypothesis(const std::map<int, float> & posterior,
											const std::map<int, float> & likelihood,
											bool neighborSumUsed,
											bool likelihoodUsed) const;

private:
	// Modifiable parameters
	bool _publishStats;
	bool _publishRawData;
	bool _publishPdf;
	bool _publishLikelihood;
	bool _publishSensorData;
	float _maxTimeAllowed; // in ms
	unsigned int _maxMemoryAllowed; // signatures count in WM
	int _sensorsBufferMaxSize;
	float _loopThr;
	float _loopRatio;
	float _loopSimilarity;
	float _retrievalThr;
	unsigned int _maxRetrieved;
	bool _selectionNeighborhoodSummationUsed;
	bool _selectionLikelihoodUsed;
	bool _actionsSentRejectHyp;
	float _confidenceThr;
	bool _likelihoodStdDevRemoved;
	bool _likelihoodNullValuesIgnored;
	unsigned int _neighborhoodActionsSelection;

	int _lcHypothesisId;
	int _reactivateId;
	float _lastLcHypothesisValue;
	int _lastLoopClosureId;
	NeighborLink _actuatorsLink;

	BayesFilter * _bayesFilter;

	Memory * _memory;

	std::string _wDir;

	Statistics statistics_;
};

#endif /* SEMOL_H_ */

} // namespace rtabmap
